package cn.com.wangluotongxin.linux.service.impl;

import cn.com.wangluotongxin.common.exceptions.BadResponseException;
import cn.com.wangluotongxin.linux.constants.FileTypeEnum;
import cn.com.wangluotongxin.linux.service.IFileService;
import cn.hutool.core.io.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FileServiceImpl implements IFileService {

    private final static List<String> txtTypes = Arrays.asList(".txt", ".sh", ".js", ".vue", ".css", ".html", ".htm", ".conf");

    private final static List<String> fileUpdateTypes = Arrays.asList(".txt", ".sh", ".js", ".vue", ".css", ".html", ".htm", ".conf");

    @Override
    public void uploadFile(MultipartFile file, String filePath) {
        try {
            // 确保目录存在
            Path uploadDirectory = Paths.get(filePath);
            // 文件存储路径
            Path fileUploadPath = uploadDirectory.resolve(file.getOriginalFilename());
            // 覆盖已存在的文件
            Files.copy(file.getInputStream(), fileUploadPath, StandardCopyOption.REPLACE_EXISTING);
        }catch (Exception ex) {
            log.error("文件上传失败:{}", ex.getMessage());
            throw new BadResponseException("文件上传失败");
        }
    }

    @Override
    public void removeFile(String filePath, String fileName) {
        String localFilePath = filePath.concat("/").concat(fileName);
        File localFile = new File(localFilePath);
        if(!localFile.exists()) {
            throw new BadResponseException("文件不存在");
        }
        if(!localFile.isFile()) {
            throw new BadResponseException("非文件不支持删除");
        }
        try {
            Files.delete(localFile.toPath());
        }catch (Exception e) {
            log.error("文件删除失败，路径={}， error={}", localFilePath, e.getMessage());
            throw new BadResponseException("文件删除失败");
        }
    }

    @Override
    public void createFile(String filePath, String fileName, FileTypeEnum fileTypeEnum) {
        String fileDirPath = filePath.concat("/").concat(fileName).concat(fileTypeEnum.getSuffix().trim());
        File localFile = new File(fileDirPath);
        if(Files.exists(localFile.toPath())) {
            throw new BadResponseException("文件已存在");
        }
        try{
            localFile.createNewFile();
        }catch (Exception e) {
            log.error("创建文件失败，路径={}， error={}", fileDirPath, e.getMessage());
            throw new BadResponseException("文件创建失败");
        }
    }

    @Override
    public Object readFile(String filePath, String fileName) {
        String fileDirPath = filePath.concat("/").concat(fileName);
        File localFile = new File(fileDirPath);
        if(!localFile.isFile()) {
            throw new BadResponseException("请选择文件");
        }
        if(this.isTxtRead(fileName)) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(FileUtil.getInputStream(localFile), StandardCharsets.UTF_8));

            StringBuilder fileContent = new StringBuilder();
            for(String line : reader.lines().collect(Collectors.toList())) {
                fileContent.append(line + "<br/>");
            }
            return fileContent.toString();
        }else {
            throw new BadResponseException("不支持该文件阅读");
        }
    }

    @Override
    public void writeFile(String filePath, String fileName, String content) {
        if(!this.isUpdateFile(fileName)) {
            throw new BadResponseException("文件不支持修改");
        }
        String fileDirPath = filePath.concat("/").concat(fileName);
        File localFile = new File(fileDirPath);
        if(!localFile.isFile()) {
            throw new BadResponseException("请选择文件");
        }
        if(content == null) return;

        try {
            Files.write(Paths.get(fileDirPath), content.getBytes(), StandardOpenOption.TRUNCATE_EXISTING);
        } catch (Exception e) {
            log.error("写入文件内容异常:{}", e.getMessage());
            throw new BadResponseException("文件保存失败:" + e.getMessage());
        }
    }

    private Boolean isTxtRead(String fileName) {
        if(fileName.indexOf(".") <= 0 || fileName.endsWith(".")) {
            return true;
        }
        for(String str : txtTypes) {
            if(fileName.endsWith(str)) {
                return true;
            }
        }
        return false;
    }

    private Boolean isUpdateFile(String fileName) {
        if(fileName.indexOf(".") <= 0 || fileName.endsWith(".")) {
            return true;
        }
        for(String str : fileUpdateTypes) {
            if(fileName.endsWith(str)) {
                return true;
            }
        }
        return false;
    }
}
